package com.xiao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiao.domain.ResponseResult;
import com.xiao.domain.constants.SystemConstants;
import com.xiao.domain.dto.AddRoleDto;
import com.xiao.domain.dto.RoleChangeStatusDto;
import com.xiao.domain.dto.SysRoleDto;
import com.xiao.domain.pojo.SysRoleMenu;
import com.xiao.domain.vo.*;
import com.xiao.enums.AppHttpCodeEnum;
import com.xiao.mapper.SysRoleMapper;
import com.xiao.domain.pojo.SysRole;
import com.xiao.service.SysRoleMenuService;
import com.xiao.service.SysRoleService;
import com.xiao.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

// 角色信息表 业务接口实现
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Override
    public List<String> selectRolekeyByUserId(Long userId) {

        if (userId==1L){ // 如果是管理员 只需要 展示 admin 即可
            ArrayList<String> roleKeys = new ArrayList<>();
            roleKeys.add("admin");
            return roleKeys;
        } else { // 否则按照用户ID 查询 角色关键字
            List<String> list = this.getBaseMapper().selectRolekeyByUserId(userId);
            return list;
        }

    }

    @Override
    public ResponseResult<PageVo> roleList(Integer pageNum, Integer pageSize, SysRoleDto sysRoleDto) {


        // 1. 构建查询条件
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        // 转化成 pojo 配合查询
        SysRole sysRole = BeanCopyUtils.copyBean(sysRoleDto, SysRole.class);
        wrapper.like(StringUtils.hasText(sysRole.getRoleName()),SysRole::getRoleName,sysRole.getRoleName());
        wrapper.eq(StringUtils.hasText(sysRole.getStatus()),SysRole::getStatus,sysRole.getStatus());
        wrapper.orderByAsc(SysRole::getRoleSort);

        // 2. 分页
        Page<SysRole> rolePage = new Page<>();
        rolePage.setCurrent(pageNum);//setCurrent 当前页
        rolePage.setSize(pageSize);

        // 3.查询
        Page<SysRole> page = this.page(rolePage, wrapper);
        List<SysRole> records = page.getRecords();


        // 4. 转化成 VO
        List<SysRoleVo> sysRoleVos = BeanCopyUtils.copyBeanList(records, SysRoleVo.class);


        // 5. 封装成 pageVo
        PageVo pageVo = new PageVo(sysRoleVos, page.getTotal());

        // 6.统一响应
        ResponseResult<PageVo> responseResult = ResponseResult.okResult(pageVo);


        return responseResult;
    }

    @Override
    public ResponseResult roleChangeStatus(RoleChangeStatusDto roleChangeStatusDto) {
        // 1. 转化为 pojo 映射
        SysRole sysRole = BeanCopyUtils.copyBean(roleChangeStatusDto, SysRole.class);
        sysRole.setId(roleChangeStatusDto.getRoleId()); // 前端传递参数为 roleId 我们需要映射到 id
        // 2. 发起修改
        boolean flag = this.updateById(sysRole);

        // 3. 统一响应
        ResponseResult responseResult;

        if (flag){
            responseResult=ResponseResult.okResult();
        }else {
            responseResult=ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
        }

        return responseResult;
    }

    @Autowired
    SysRoleMenuService sysRoleMenuService;
    @Override
    @Transactional // 因为这里涉及到两个表的存储，所以需要事务的支持
    public ResponseResult addRole(AddRoleDto addRoleDto) {
        // 1. 转化成 SysRole Vo
        SysRole sysRole = BeanCopyUtils.copyBean(addRoleDto, SysRole.class);

        // 2. 角色表 执行插入
        boolean isSave = this.save(sysRole);

        // 3. 角色与菜单管理表
        List<String> menuIds = addRoleDto.getMenuIds();

        boolean saveBatch =true;
        if (menuIds.size()>0){
            List<SysRoleMenu> roleMenuList = addRoleDto.getMenuIds()
                    .stream()
                    .map(id -> new SysRoleMenu(sysRole.getId(), Long.valueOf(id)))
                    .collect(Collectors.toList());
            // 4.角色菜单关联表 执行插入
            saveBatch = sysRoleMenuService.saveBatch(roleMenuList);
        }


        // 3. 统一响应
        ResponseResult responseResult ;
        if (isSave&&saveBatch){
            responseResult=ResponseResult.okResult();
        }else {
            responseResult=ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
        }
        return responseResult;
    }

    @Override
    public ResponseResult delRoleById(List<Long> ids) {
        Integer i = this.getBaseMapper().deleteBatchIds(ids);
        // 统一响应
        ResponseResult responseResult;
        if (i.equals(ids.size())){
            responseResult=ResponseResult.okResult();
        }else {
            responseResult=ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
        }

        return responseResult;
    }

    @Override
    public ResponseResult<SysRoleByIdVo> getRoleById(Long id) {
        // 1. 根据 ID 返回 角色
        SysRole sysRole = this.baseMapper.selectById(id);
        // 2. 封装Vo
        SysRoleByIdVo sysRoleByIdVo = BeanCopyUtils.copyBean(sysRole, SysRoleByIdVo.class);
        // 3. 统一响应
        ResponseResult<SysRoleByIdVo> result = ResponseResult.okResult(sysRoleByIdVo);

        return result;
    }

    @Override
    @Transactional // 因为涉及到两个表;需要添加事务支持
    public ResponseResult updateRoleMenu(RoleMenuDto roleMenuDto) {
        // 1. 修改角色信息
        SysRole sysRole = BeanCopyUtils.copyBean(roleMenuDto, SysRole.class);

        boolean isUpdate = this.updateById(sysRole);

        // 2. 修改角色关联菜单信息
        List<String> menuIds = roleMenuDto.getMenuIds();
        // 2.1 删除原有的关系

        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId,roleMenuDto.getId());
        sysRoleMenuService.getBaseMapper().delete(wrapper);// 原本也许没有关联 因此是 0
        // 2.2 插入新的关系
        boolean batch =true;
        if (menuIds.size()>0){
            List<SysRoleMenu> collect = menuIds.stream()
                    .map(m -> new SysRoleMenu(roleMenuDto.getId(), Long.valueOf(m)))
                    .collect(Collectors.toList());
             batch = sysRoleMenuService.saveBatch(collect);
        }


        // 3. 统一响应
        ResponseResult responseResult;
        if (batch&isUpdate){
            responseResult = ResponseResult.okResult();
        }else {
            responseResult = ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
        }

        return responseResult;
    }

    @Override
    public List<AllRoleListVo> getAllRoleList() {
        // 1. 查询 状态正常角色列表
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getStatus, SystemConstants.STATUS_NORMAL);
        wrapper.orderByAsc(SysRole::getRoleSort);
        List<SysRole> list = this.list(wrapper);
        // 2. 转化vo
        List<AllRoleListVo> allRoleListVos = BeanCopyUtils.copyBeanList(list, AllRoleListVo.class);

        return allRoleListVos;
    }


}


